/**
 * 在这里定义和用户相关的路由处理函数，供 /router/user.js 模块进行调用
 */

//导入数据库操作模块
const db = require("../db/index");
const bcrypt = require("bcryptjs");
// 用这个包来生成 Token 字符串
const jwt = require("jsonwebtoken");
// 导入配置文件
const config = require("../config");
const { query } = require("express");

require("dotenv").config(); // 加载环境变量

const nodemailer = require("nodemailer");
const crypto = require("crypto");

// 注册用户的处理函数
// 配置邮件传输
const transporter = nodemailer.createTransport({
  host: process.env.MAIL_HOST,
  port: process.env.MAIL_PORT,
  secure: process.env.MAIL_PORT == 465, // 使用 465 端口时，secure 设置为 true
  // port: 465, // 使用 587 端口时，secure 设置为 false
  // secure: true, // 587 端口使用 false，465 端口使用 true
  auth: {
    user: process.env.MAIL_USER,
    pass: process.env.MAIL_PASS,
  },
});

// 发送验证码的函数

exports.sendVerificationCode = (req, res) => {
  const { email } = req.body;
  console.log("Request body:", req.body);
  console.log("Email:", email);

  // 生成6位验证码
  const code = crypto.randomInt(100000, 999999).toString();
  const expiry = new Date(Date.now() + 3 * 60 * 1000); // 3分钟后过期

  // 检查邮箱是否已注册
  const checkEmailSql = "SELECT is_registered FROM zc_users WHERE email = ?";

  db.query(checkEmailSql, [email], (err, results) => {
    if (err) {
      console.error("检查邮箱时出错:", err);
      return res.status(500).json({ code: 1, message: "数据库错误" });
    }

    console.log("查询结果:", results); // 输出查询结果以进行调试

    if (results.length === 0) {
      // 如果邮箱未注册，插入新的记录
      const insertSql = `
        INSERT INTO zc_users (email, code, expiry, is_registered)
        VALUES (?, ?, ?, 0)
      `;

      db.query(insertSql, [email, code, expiry], (err, results) => {
        if (err) {
          console.error("插入新记录时出错:", err);
          return res.status(500).json({ code: 1, message: "数据库错误" });
        }

        sendVerificationEmail();
      });
    } else {
      const isRegistered = results[0].is_registered;

      if (isRegistered === 1) {
        return res.status(400).json({ code: 1, message: "邮箱已注册" });
      }

      // 如果未注册，更新验证码和过期时间
      const updateSql = `
        UPDATE zc_users
        SET code = ?, expiry = ?
        WHERE email = ?
      `;

      db.query(updateSql, [code, expiry, email], (err, results) => {
        if (err) {
          console.error("更新记录时出错:", err);
          return res.status(500).json({ code: 1, message: "数据库错误" });
        }

        sendVerificationEmail();
      });
    }
    function sendVerificationEmail() {
      // 发送验证码到用户邮箱
      const mailOptions = {
        from: `"站村云站" <${process.env.MAIL_USER}>`,
        to: email,
        subject: "注册验证",
        html: `<p>您的验证码是: <br><span style="font-size: 30px; font-weight: bold;">${code}</span> <br>有效期为3分钟。</p>`,
      };

      console.log("Mail options:", mailOptions);

      transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
          console.error("发送电子邮件时出错:", error);
          return res
            .status(500)
            .json({ code: 1, message: "发送电子邮件时出错" });
        }
        res.status(200).json({ code: 0, message: "验证码已发送" });
      });
    }
  });
};

exports.regUser = (req, res) => {
  console.log("Request body:", req.body);
  const { email, code, password, username } = req.body;

  console.log("Email:", email);
  console.log("Code:", code);
  console.log("Password:", password);
  console.log("Username:", username);

  if (!email || !code || !password || !username) {
    return res.status(400).json({ code: 1, message: "所有字段都是必需的" });
  }

  // 查询数据库中的验证码
  const sqlCheck = `SELECT code, expiry, id FROM zc_users WHERE email = ?`;
  db.query(sqlCheck, [email], (err, results) => {
    if (err) {
      console.error("数据库错误:", err);
      return res.status(500).json({ code: 1, message: "数据库错误" });
    }
    if (results.length === 0) {
      return res.status(400).json({ code: 1, message: "邮箱未注册" });
    }

    const { code: storedCode, expiry, id: userId } = results[0];

    if (code !== storedCode || new Date(expiry) < Date.now()) {
      return res.status(400).json({ code: 1, message: "验证码无效或过期" });
    }

    // 更新用户信息
    const hashedPassword = bcrypt.hashSync(password, 10);
    const sqlUpdate = `
      UPDATE zc_users
      SET username = ?, password = ?, is_registered = 1
      WHERE email = ?
    `;

    db.query(sqlUpdate, [username, hashedPassword, email], (err, results) => {
      if (err) {
        console.error("数据库错误:", err);
        return res.status(500).json({ code: 1, message: "数据库错误" });
      }
      if (results.affectedRows === 0) {
        return res.status(500).json({ code: 1, message: "更新用户失败" });
      }

      // 处理推荐数据
      const defaultData = [
        [
          "站酷",
          "站酷ZCOOL,中国设计师互动平台",
          "https://www.zcool.com.cn/",
          "uploads/recommend/default-站酷.ico",
          userId,
        ],
        [
          "UI中国",
          "UI中国用户体验平台",
          "https://www.ui.cn/",
          "uploads/recommend/default-ui中国.ico",
          userId,
        ],
        [
          "dribbble",
          "全球UI设计师作品秀社区",
          "https://dribbble.com/",
          "uploads/recommend/default-dirbbble.png",
          userId,
        ],
        [
          "优设",
          "中国设计师互动平台",
          "https://www.uisdc.com/",
          "uploads/recommend/default-优设.ico",
          userId,
        ],
        [
          "figma",
          "figma官方资源社区",
          "https://www.figma.com/community/",
          "uploads/recommend/default-figma.ico",
          userId,
        ],
        [
          "百度",
          "众里寻她千百度",
          "https://www.baidu.com/",
          "uploads/recommend/default-百度.ico",
          userId,
        ],
      ];

      const sqlRecommend = `
        INSERT INTO zc_recommend (title, content, url, logoImg, user_id)
        VALUES ?
        ON DUPLICATE KEY UPDATE
          title = VALUES(title),
          content = VALUES(content),
          url = VALUES(url),
          logoImg = VALUES(logoImg)
      `;
      db.query(sqlRecommend, [defaultData], (err, results) => {
        if (err) {
          console.error("数据库错误:", err);
          return res.status(500).json({ code: 1, message: "数据库错误" });
        }
        res.status(200).json({ code: 0, message: "注册成功" });
        // // 清除验证码数据
        // const deleteCodeSql = `DELETE FROM zc_users WHERE email = ?`;
        // db.query(sqlRecommend, [email], (err) => {
        //   if (err) {
        //     console.error('清除验证码时出错:', err);
        //     return res.status(500).json({ code: 1, message: '清除验证码时出错' });
        //   }
        //   res.status(200).json({ code: 0, message: '注册成功' });
        // });
      });
    });
  });
};

// 登录的处理函数
exports.login = (req, res) => {
  //接收表单数据
  const userinfo = req.body;

  //定义 SQL 语句
  const sql = `select * from zc_users where email = ?`;

  //执行 SQL 语句，查询用户的数据
  db.query(sql, userinfo.email, function (err, results) {
    // 执行 SQL 语句失败
    if (err) return res.cc(err);
    // 执行 SQL 语句成功，但是查询到数据条数不等于 1
    if (results.length !== 1) return res.cc("邮箱未被注册");

    // TODO：判断用户输入的登录密码是否和数据库中的密码一致
    // 拿着用户输入的密码,和数据库中存储的密码进行对比
    const compareResult = bcrypt.compareSync(
      userinfo.password,
      results[0].password
    );
    // 如果对比的结果等于 false, 则证明用户输入的密码错误
    if (!compareResult) {
      return res.cc("密码错误");
    }

    // TODO：登录成功，生成 Token 字符串
    // 剔除完毕之后，user 中只保留了用户的 id, username, email 这3个属性的值
    const user = { ...results[0], password: "" };
    // 生成 Token 字符串
    const tokenStr = jwt.sign(user, config.jwtSecretKey, {
      expiresIn: "100h", // token 有效期为 100 个小时
      // expiresIn: "3m", // token 有效期为 3 分钟
    });
    //将生成的 Token 字符串响应给客户端
    res.send({
      status: 0,
      message: "登录成功",
      // 为了方便客户端使用 Token，在服务器端直接拼接上 Bearer 的前缀
      token: "Bearer " + tokenStr,
      userId: user.id,
      username: user.username,
    });
  });

  //   res.send("login OK");
};
